﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using CppIDE.Core;
using Application = CppIDE.Core.Application;

namespace CppIDE.UI
{

    /// <summary>
    /// A projektet fa formában megjelenítő osztály: a projektfa.
    /// </summary>
    class ProjectTree : TreeView
    {

        /// <summary>
        /// Jobbklikk-menü: itt érhető el az eltávolítás a projektből.
        /// </summary>
        ContextMenu menu;

        /// <summary>
        /// Konstruktor, létrehoz egy új projektfát.
        /// </summary>
        public ProjectTree()
        {
            Application.getInstance().ActiveProjectChange += new EventHandler(ActiveProjectChange);
            update();
            menu = new ContextMenu();
        }

        /// <summary>
        /// Ha az aktuális projekt megváltozik, ez meghívódik.
        /// Frissíti a projektfát.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ActiveProjectChange(object sender, EventArgs e)
        {
            update();
        }

        /// <summary>
        /// Felépíti a jobbklikk menüt.
        /// </summary>
        private void buildMenu()
        {
            menu.MenuItems.Clear();
            if (SelectedNode == null) return;
            if (SelectedNode.Tag is SourceFile)
            {
                MenuItem open = new MenuItem("Megnyitás");
                open.DefaultItem = true;
                open.Click += new EventHandler(OpenClick);
                menu.MenuItems.Add(open);
                MenuItem remove = new MenuItem("Eltávolítás");
                remove.Click += new EventHandler(RemoveClick);
                menu.MenuItems.Add(remove);
                MenuItem delete = new MenuItem("Törlés");
                delete.Click += new EventHandler(DeleteClick);
                menu.MenuItems.Add(delete);
            }
        }

        /// <summary>
        /// Ha a jobbklikk-menüben a megnyitásra kattintanak, ez hajtódik végre:
        /// aktiválja a kiválasztott elemhez társított forrásfájl fülét.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void OpenClick(object sender, EventArgs e)
        {
            if (SelectedNode == null) return;
            if (SelectedNode.Tag is SourceFile)
            {
                MainForm.getInstance().open(SelectedNode.Tag as SourceFile);
            }
        }

        /// <summary>
        /// Ha a jobbklikk-menüben az eltávolításra kattintanak, ez hajtódik végre:
        /// eltávolítja a kiválasztott elemhez társított forrásfájlt az aktuális
        /// projektből.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void RemoveClick(object sender, EventArgs e)
        {
            if (SelectedNode == null) return;
            if (SelectedNode.Tag is SourceFile)
            {
                Project project = Application.getInstance().ActiveProject;
                project.removeFile(SelectedNode.Tag as SourceFile);
            }
        }

        /// <summary>
        /// Ha a jobbklikk-menüben a törlésre kattintanak, ez hajtódik végre:
        /// eltávolítja a kiválasztott elemhez társított forrásfájlt az aktuális
        /// projektből, majd törli a fájlrendszerről.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void DeleteClick(object sender, EventArgs e)
        {
            if (SelectedNode == null) return;
            if (SelectedNode.Tag is SourceFile)
            {
                Project project = Application.getInstance().ActiveProject;
                SourceFile file = SelectedNode.Tag as SourceFile;
                project.removeFile(file);
                file.Delete();
            }
        }

        /// <summary>
        /// Frissíti/felépíti a projektfát.
        /// </summary>
        public void update()
        {
            Nodes.Clear();
            Application application = Application.getInstance();
            if (application.isProjectLoaded())
            {
                Project project = application.ActiveProject;
                TreeNode cppNode = new TreeNode("C++ fájlok");
                TreeNode headerNode = new TreeNode("Header fájlok");
                foreach (SourceFile file in project)
                {
                    TreeNode fileNode = new TreeNode(file.Name);
                    fileNode.Tag = file;
                    if (file is CppFile)
                    {
                        cppNode.Nodes.Add(fileNode);
                    }
                    else if (file is HeaderFile)
                    {
                        headerNode.Nodes.Add(fileNode);
                    }
                }
                TreeNode projectNode = new TreeNode(project.Name);
                if (!project.Saved)
                {
                    projectNode.Text += "*";
                }
                projectNode.Nodes.Add(cppNode);
                projectNode.Nodes.Add(headerNode);
                Nodes.Add(projectNode);
                projectNode.ExpandAll();
            }
            else
            {
                Nodes.Add(new TreeNode("Nincs aktív projekt!"));
            }
        }

        override protected void OnDoubleClick(EventArgs e)
        {
            if (SelectedNode == null) return;
            if (SelectedNode.Tag is SourceFile)
            {
                MainForm.getInstance().open(SelectedNode.Tag as SourceFile);
            }
        }

        protected override void OnClick(EventArgs e)
        {
            if (e is MouseEventArgs)
            {
                MouseEventArgs mouseEventArgs = e as MouseEventArgs;
                if (mouseEventArgs.Button == MouseButtons.Right)
                {
                    TreeNode node = GetNodeAt(mouseEventArgs.Location);
                    if (node != null)
                    {
                        SelectedNode = node;
                        buildMenu();
                        if (menu.MenuItems.Count > 0)
                        {
                            menu.Show(this, mouseEventArgs.Location);
                        }
                    }
                }
                else
                {
                    base.OnClick(mouseEventArgs);
                }
            }
            else
            {
                base.OnClick(e);
            }
        }

    }

}
